<?php
/**
 * class GF
 *
 * 全局公共函数
 *
 * @author:
*/
define ( 'VISIBLE_CHARS', 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-=~!@#$%^&*()_+[];,./{}|:<>?' );
final class GF {
	static function oops($msg) {
		$html = <<<EOT
<html>
  <head>
    <title>ERROR</title>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
  </head>
  <body>
	{$msg}
  </body>
</html>
EOT;
		print $html;
		exit ();
	}
	static function GetFileFolder($path = null) {
		if (! empty ( $path )) {
			$path = preg_replace ( '/\\\/', '/', $path );
			return substr ( $path, 0, strrpos ( $path, '/' ) );
		}
		return '.';
	}
	static function SetDateTimeZone($tz = null) {
		if ($tz != null && function_exists ( 'date_default_timezone_set' ))
			date_default_timezone_set ( $tz );
	}
	static function MagicAddSlashes(&$v) {
		if (get_magic_quotes_gpc ()) {
			return;
		}
		if (is_array ( $v )) {
			foreach ( $v as $k => $o ) {
				if (is_array ( $o )) {
					self::MagicAddSlashes ( $v [$k] );
				} else {
					$v [$k] = addslashes ( $o );
				}
			}
		} else {
			$v = addslashes ( $v );
		}
	}
	static function MagicRmSlashes(&$v) {
		if (! get_magic_quotes_gpc ()) {
			return;
		}
		if (is_array ( $v )) {
			foreach ( $v as $k => $o ) {
				if (is_array ( $o )) {
					self::MagicRmSlashes ( $v [$k] );
				} else {
					$v [$k] = stripslashes ( $o );
				}
			}
		} else {
			$v = stripslashes ( $v );
		}
	}
	static function GetTemplate($tpl, $tpl_name = 'default') {
		if (! defined ( 'ROOT_PATH' )) {
			self::oops ( 'Constant \'ROOT_PATH\' is not defined' );
		}
		$path = ROOT_PATH . './templates/' . $tpl_name . '/' . $tpl;
		if (file_exists ( $path )) {
			return $path;
		} else {
			return null;
		}
	}
	static function GetSystemConfig() {
		if (! defined ( 'ROOT_PATH' )) {
			self::oops ( 'Constant \'ROOT_PATH\' is not defined' );
		}
	}
	static function Unregister_GLOBALS() {
		if (! ini_get ( 'register_globals' ))
			return;
		
		if (isset ( $_REQUEST ['GLOBALS'] ))
			die( /*WP_I18N_GLOBALS_OVERWRITE*/'检测到 GLOBALS 的改写尝试'/*/WP_I18N_GLOBALS_OVERWRITE*/ );
			
			// Variables that shouldn't be unset
		$no_unset = array (
				'GLOBALS',
				'_GET',
				'_POST',
				'_COOKIE',
				'_REQUEST',
				'_SERVER',
				'_ENV',
				'_FILES',
				'table_prefix' 
		);
		
		$input = array_merge ( $_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset ( $_SESSION ) && is_array ( $_SESSION ) ? $_SESSION : array () );
		foreach ( $input as $k => $v )
			if (! in_array ( $k, $no_unset ) && isset ( $GLOBALS [$k] )) {
				$GLOBALS [$k] = null;
				unset ( $GLOBALS [$k] );
			}
	}
	static function Fix_server_vars() {
		global $PHP_SELF;
		
		$default_server_values = array (
				'SERVER_SOFTWARE' => '',
				'REQUEST_URI' => '' 
		);
		
		$_SERVER = array_merge ( $default_server_values, $_SERVER );
		
		// Fix for IIS when running with PHP ISAPI
		if (empty ( $_SERVER ['REQUEST_URI'] ) || (php_sapi_name () != 'cgi-fcgi' && preg_match ( '/^Microsoft-IIS\//', $_SERVER ['SERVER_SOFTWARE'] ))) {
			
			// IIS Mod-Rewrite
			if (isset ( $_SERVER ['HTTP_X_ORIGINAL_URL'] )) {
				$_SERVER ['REQUEST_URI'] = $_SERVER ['HTTP_X_ORIGINAL_URL'];
			} 			// IIS Isapi_Rewrite
			else if (isset ( $_SERVER ['HTTP_X_REWRITE_URL'] )) {
				$_SERVER ['REQUEST_URI'] = $_SERVER ['HTTP_X_REWRITE_URL'];
			} else {
				// Use ORIG_PATH_INFO if there is no PATH_INFO
				if (! isset ( $_SERVER ['PATH_INFO'] ) && isset ( $_SERVER ['ORIG_PATH_INFO'] ))
					$_SERVER ['PATH_INFO'] = $_SERVER ['ORIG_PATH_INFO'];
					
					// Some IIS + PHP configurations puts the script-name in the
					// path-info (No need to append it twice)
				if (isset ( $_SERVER ['PATH_INFO'] )) {
					if ($_SERVER ['PATH_INFO'] == $_SERVER ['SCRIPT_NAME'])
						$_SERVER ['REQUEST_URI'] = $_SERVER ['PATH_INFO'];
					else
						$_SERVER ['REQUEST_URI'] = $_SERVER ['SCRIPT_NAME'] . $_SERVER ['PATH_INFO'];
				}
				
				// Append the query string if it exists and isn't null
				if (! empty ( $_SERVER ['QUERY_STRING'] )) {
					$_SERVER ['REQUEST_URI'] .= '?' . $_SERVER ['QUERY_STRING'];
				}
			}
		}
		// Fix for PHP as CGI hosts that set SCRIPT_FILENAME to something ending
		// in php.cgi for all requests
		if (isset ( $_SERVER ['SCRIPT_FILENAME'] ) && (strpos ( $_SERVER ['SCRIPT_FILENAME'], 'php.cgi' ) == strlen ( $_SERVER ['SCRIPT_FILENAME'] ) - 7))
			$_SERVER ['SCRIPT_FILENAME'] = $_SERVER ['PATH_TRANSLATED'];
			
			// Fix for Dreamhost and other PHP as CGI hosts
		if (strpos ( $_SERVER ['SCRIPT_NAME'], 'php.cgi' ) !== false)
			unset ( $_SERVER ['PATH_INFO'] );
			
			// Fix empty PHP_SELF
		$PHP_SELF = $_SERVER ['PHP_SELF'];
		if (empty ( $PHP_SELF ))
			$_SERVER ['PHP_SELF'] = $PHP_SELF = preg_replace ( '/(\?.*)?$/', '', $_SERVER ["REQUEST_URI"] );
	}
	
	/**
	 * 以$seed为字典，生成随机的字符串<br />
	 * $seed省略的话则使用全部（除过反斜线\)的可见字符
	 *
	 * @param int $len        	
	 * @param string $seed        	
	 * @return string
	 */
	static function GenerateRandomString($len = 16, $seed = VISIBLE_CHARS) {
		$str = '';
		$dictlen = strlen ( $seed );
		for($i = 0; $i < $len; $i ++) {
			$index = rand ( 0, $dictlen - 1 );
			$str .= substr ( $seed, $index, 1 );
		}
		// $str = addcslashes ( $str, '\\' );
		return $str;
	}
	
	/**
	 *
	 * @param string $seed        	
	 * @param int $len        	
	 * @return string
	 */
	static function GenerateToken($seed = VISIBLE_CHARS, $len = 32) {
		return sha1 ( self::GenerateRandomString ( $len, $seed ) );
	}
	
	/**
	 * <h2>生成密码Salt</h2>
	 *
	 * @param string $seed
	 *        	Salt中字符的选择空间
	 * @param int $len
	 *        	默认值16
	 * @return string
	 */
	static function GenerateSalt($seed = VISIBLE_CHARS, $len = 16) {
		return self::GenerateRandomString ( $len, $seed );
	}
	
	/**
	 * getRemoteIP
	 * 获取远程客户端的IP地址
	 *
	 * @return string
	 */
	static function GetRemoteIP() {
		// return $_SERVER ['REMOTE_ADDR'];
		if (getenv ( "HTTP_CLIENT_IP" ) && strcasecmp ( getenv ( "HTTP_CLIENT_IP" ), "unknown" ))
			$ip = getenv ( "HTTP_CLIENT_IP" );
		else if (getenv ( "HTTP_X_FORWARDED_FOR" ) && strcasecmp ( getenv ( "HTTP_X_FORWARDED_FOR" ), "unknown" ))
			$ip = getenv ( "HTTP_X_FORWARDED_FOR" );
		else if (getenv ( "REMOTE_ADDR" ) && strcasecmp ( getenv ( "REMOTE_ADDR" ), "unknown" ))
			$ip = getenv ( "REMOTE_ADDR" );
		else if (isset ( $_SERVER ['REMOTE_ADDR'] ) && $_SERVER ['REMOTE_ADDR'] && strcasecmp ( $_SERVER ['REMOTE_ADDR'], "unknown" ))
			$ip = $_SERVER ['REMOTE_ADDR'];
		else
			$ip = "unknown";
		return ($ip);
	}
	static function GenerateFormId() {
		return 'form' . md5 ( self::GenerateRandomString ( 8 ) );
	}
	
	/**
	 * <h2>根据表创建对应的类</h2>
	 *
	 * @param IConnector $db
	 *        	提供数据库访问的数据库连接对象
	 * @param string $tableName
	 *        	要导出的表名
	 * @param string $className
	 *        	创建的类名
	 * @param string $path
	 *        	导出文件的存放路径
	 * @param string $fileName
	 *        	导出文件名
	 * @return boolean 成功返回true，否则false
	 */
	static function CreateTableClass($db, $tableName, $className, $path) {
		if (empty ( $db ) || empty ( $tableName ) || ! is_string ( $className ) || ! is_string ( $path )) {
			return false;
		}
		$fileName = $className . '.class.php';
		try {
			if (! is_writable ( $path )) {
				throw new ExceptionEx ( "Directory is not writable" );
			}
			if (! ($handle = fopen ( $path . $fileName, "w" ))) {
				throw new ExceptionEx ( "Cannot create File" );
			}
			fwrite ( $handle, "<?php\n" );
			fwrite ( $handle, "class {$className} {\n" );
			$sql = 'desc ' . $tableName;
			// $param = array (
			// 'tname' => $tableName
			// );
			// $map [] = array (
			// 'tname',
			// 'string'
			// );
			$rs = $db->select ( $sql );
			$i = 0;
			while ( $i < sizeof ( $rs ) ) {
				echo $rs [$i] ['Field'], '<br />';
				
				fwrite ( $handle, "\tpublic $" . $rs [$i] ['Field'] . ";\n" );
				$i ++;
			}
			fwrite ( $handle, "}" );
			fclose ( $handle );
		} catch ( ExceptionEx $e ) {
			Logger::configure ( ROOT_PATH . 'config/log_config.xml' );
			$logger = Logger::getLogger ( __CLASS__ );
			$logger->error ( $e->getMessage () . '  ' . __CLASS__ . '  ' . __FUNCTION__ );
			return false;
		}
	}
	
	/**
	 * <h2>空操作 ，在某些场合下很有用</h2>
	 */
	public static function nop() {
	}
	
	/**
	 * <h2>saltPassword</h2>
	 *
	 * 给口令加盐
	 *
	 * @param string $password
	 *        	原始明文口令
	 * @param string $salt
	 *        	要参杂的干扰“盐分”
	 * @param int $version
	 *        	加盐算法的版本
	 * @return string 加过盐的密文口令
	 */
	public static function saltPassword($password, $salt, $version = SALT_VERSION_0) {
		$salted = '';
		switch ($version) {
			case SALT_VERSION_0 :
				$salted = strrev ( sha1 ( md5 ( $password ) . $salt ) );
				break;
			// TODO 增加其他加盐算法
			default :
				$salted = strrev ( sha1 ( md5 ( $password ) . $salt ) );
		}
		
		return $salted;
	}
	
	/**
	 * <h2>设置cookie，简化cookie设置的操作</h2>
	 *
	 * @param string $name        	
	 * @param mixed $value        	
	 * @param int $expire        	
	 */
	public static function setCookie($name, $value, $expire = 0) {
		setcookie ( $name, $value, $expire, COOKIE_PATH, COOKIE_DOMAIN );
	}
	
	/**
	 * <h2>删除cookie</h2>
	 *
	 * @param string $name        	
	 */
	public static function delCookie($name) {
		setcookie ( $name, '', time () - 3600, COOKIE_PATH, COOKIE_DOMAIN );
	}
}